﻿using System;
using Microsoft.Ccr.Core;
using BitTorrent.Agents.Messages;
using BitTorrent.Ccr.Adapters.IO;

namespace BitTorrent.Agents
{
    internal class TcpAcceptorAgent : AgentBase
    {        
        private bool _shutdownReceived;

        public TcpAcceptorAgent(DispatcherQueue dispatcherQueue)
            : base(dispatcherQueue) {
            AcceptedSocketPort = new Port<SocketAgent>();
            Port = new Port<ListenOn>();

            Activate(
                Arbiter.Interleave(
                    new TeardownReceiverGroup(Arbiter.Receive(false, CleanupPort, s => _shutdownReceived = true)),
                    new ExclusiveReceiverGroup(Arbiter.Receive(true, Port, ListenOnHandler)),
                    new ConcurrentReceiverGroup())
                );

        }

        public Port<SocketAgent> AcceptedSocketPort { get; private set; }

        public Port<ListenOn> Port { get; private set; }

        private void ListenOnHandler(ListenOn message) {
            var resultPort = SocketAdapter.Accept(message.Port, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp, message.Backlog, this.TaskQueue);

            Activate(Arbiter.Choice(resultPort,
                socket => AcceptedSocketPort.Post(new SocketAgent(socket, this.TaskQueue)),
                error => {
                    // REVISIT (fen): Take care of the error correctly 
                }));
        }
    }
}
